package com.awenhui.demo.core.utils.icbc;

import com.awenhui.demo.core.utils.RSA;
import org.apache.commons.lang3.StringUtils;

import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 工行签名帮助类
 *
 * @author yuxf
 * @version 1.0
 * @date 2020/7/7 17:07
 */
public class IcbcSign {

    public static String ENV = "PRO";//SANDBOX-沙箱，TEST-测试，PRO-正式,TEMP-临时测试
    //二维码支付公钥
    public static String QRCODE_PUBLIC_KEY;
    //二维码支付私钥
    public static String QRCODE_PRIVATE_KEY;
    //工行APP_ID
    public static String APP_ID;
    //商户编号
    public static String MER_ID;
    //网关公钥
    public static String GATEWAY_PUBLIC_KEY;
    //收单协议编号
    public static String MER_PRTCL_NO;
    //收款账号
    public static String MER_ACCT;
    //E生活商户号
    public static String ELIFE_MER_ID;

    //PC端支付费率
    public static String PAY_RATE_PC = "0.002";
    public static String API_HOST;


    private static String DATA = "/api/preciousmetal/V1/purchase?app_id=2014072300007148&biz_content={\"id\":\"student_id\",\"name\":\"student_name\"}&charset=GBK&sign_type=RSA&timestamp=2014‐07‐24 03:07:50&trade_id=123456";
    private static String SIGN = "A7ibf97cez7UudFZCSePEn8kgr0DSDlvu+CqCAm0JJ65xsQtU7vFuGAwPoUfPYVWG2q+9DXbL4el8pAq6TPicg8Nn/zCCGGF4PRSmi4ZLzU+7fhrsMMo5hMhhQhLhYplbvHLwsRy/XqF8o49g2+es9ZX4mzpVR/gwMcINi8rXlE=";

    static {
        switch (ENV) {
            case "TEMP":
                QRCODE_PUBLIC_KEY = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCwFgHD4kzEVPdOj03ctKM7KV+16bWZ5BMNgvEeuEQwfQYkRVwI9HFOGkwNTMn5hiJXHnlXYCX+zp5r6R52MY0O7BsTCLT7aHaxsANsvI9ABGx3OaTVlPB59M6GPbJh0uXvio0m1r/lTW3Z60RU6Q3oid/rNhP3CiNgg0W6O3AGqwIDAQAB";
                QRCODE_PRIVATE_KEY = "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBALAWAcPiTMRU906PTdy0ozspX7XptZnkEw2C8R64RDB9BiRFXAj0cU4aTA1MyfmGIlceeVdgJf7OnmvpHnYxjQ7sGxMItPtodrGwA2y8j0AEbHc5pNWU8Hn0zoY9smHS5e+KjSbWv+VNbdnrRFTpDeiJ3+s2E/cKI2CDRbo7cAarAgMBAAECgYABiA933q4APyTvf/uTYdbRmuiEMoYr0nn/8hWayMt/CHdXNWs5gLbDkSL8MqDHFM2TqGYxxlpOPwnNsndbW874QIEKmtH/SSHuVUJSPyDW4B6MazA+/e6Hy0TZg2VAYwkB1IwGJox+OyfWzmbqpQGgs3FvuH9q25cDxkWntWbDcQJBAP2RDXlqx7UKsLfM17uu+ol9UvpdGoNEed+5cpScjFcsB0XzdVdCpp7JLlxR+UZNwr9Wf1V6FbD2kDflqZRBuV8CQQCxxpq7CJUaLHfm2kjmVtaQwDDw1ZKRb/Dm+5MZ67bQbvbXFHCRKkGI4qqNRlKwGhqIAUN8Ynp+9WhrEe0lnxo1AkEA0flSDR9tbPADUtDgPN0zPrN3CTgcAmOsAKXSylmwpWciRrzKiI366DZ0m6KOJ7ew8z0viJrmZ3pmBsO537llRQJAZLrRxZRRV6lGrwmUMN+XaCFeGbgJ+lphN5/oc9F5npShTLEKL1awF23HkZD9HUdNLS76HCp4miNXbQOVSbHi2QJAUw7KSaWENXbCl5c7M43ESo9paHHXHT+/5bmzebq2eoBofn+IFsyJB8Lz5L7WciDK7WvrGC2JEbqwpFhWwCOl/w==";
                GATEWAY_PUBLIC_KEY = "3";
                break;
            case "SANDBOX":
                QRCODE_PUBLIC_KEY = "1";
                QRCODE_PRIVATE_KEY = "2";
                GATEWAY_PUBLIC_KEY = "3";
                break;
            case "TEST":
                QRCODE_PUBLIC_KEY = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAw3xpXcBW8W/ADr2cS3G5WSyWZOTd1PMb4Dh16N2aF80ZeC1hjZfxOCTBnqwojlyAsA5vU8g/rzZEtJYWtAMOf4N2L1Z6TnwhRk6lkdaLyP4Ad3y/tUJcYVBhrVNTa7Etc7hUXw89Oid12XN6qSHx0kbxULNq8rcOUrnpoEQm96ep3GPrMmtanPIhLo2w+pD4ua3m9by+Za4kKSNYfXvEYjCANo0l5bZTEPBBh0NpzCHL5xAjHYueCxvAwe/R4WMCHZjgKPC5i+tSAfeUXNXUbpyOiEZTI7nJ/1dGJTITILvku+mwcxE5TRQWCeJEnlVUPcZVibE7TZSE6vZBdTGG+QIDAQAB";
                QRCODE_PRIVATE_KEY = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDDfGldwFbxb8AOvZxLcblZLJZk5N3U8xvgOHXo3ZoXzRl4LWGNl/E4JMGerCiOXICwDm9TyD+vNkS0lha0Aw5/g3YvVnpOfCFGTqWR1ovI/gB3fL+1QlxhUGGtU1NrsS1zuFRfDz06J3XZc3qpIfHSRvFQs2rytw5SuemgRCb3p6ncY+sya1qc8iEujbD6kPi5reb1vL5lriQpI1h9e8RiMIA2jSXltlMQ8EGHQ2nMIcvnECMdi54LG8DB79HhYwIdmOAo8LmL61IB95Rc1dRunI6IRlMjucn/V0YlMhMgu+S76bBzETlNFBYJ4kSeVVQ9xlWJsTtNlITq9kF1MYb5AgMBAAECggEABXDQ/er8gHu7vK1KTE89+V1kUiqMggDCJdtsbK6+OytaKh4ZOPehnw5m1SO1fUDV1BCSyKIqI5Y/E0eaGih7ntDp2SdvAAA0bOCDeyudeFqZaLnwG/tc1tiF320SRU0JFs9qibrC2Xt/rC2qnEp1kISo8rYLo/W0UFkcR3meHAZiH4LRQ74dRH4D8ADxG4BZJfXM49+aoUuXtl6mLcUTLIm8E7qvY8Bj0zwDFgHimr93nqoLaq84trhcO+tdm6xfadBTyUtROQgchhni4fiabJWAyjfmFR0zitY5AOyxEXuICM6cXyuXH7OsuYNFgyS6WyxntvonYOxEO6ZV5KGQgQKBgQDj6WIxBL+woZv4TXfSy69X5MBZZCR76pbT/4cxwik4C45NWTkQZroFnpeNe1+ZUBCBo9yKFqJE3Lc3GDqP4ppyae8ncEt8573BFtgm9/W2+8ktPHpTP69sBPR3cU+qJmGywvhmGbsKw3OAc1hh8QUfB5wWiHGpk9d2n6Oesar8QwKBgQDbk/9fbuFqvR8U8l2SVNo9I6wHuEMi6n+Xvyxa4in+o2sYRexZFXj+V2wG2cnnac/VwLjrc3QZeFjlIeeR2XPq51k3XvJbeDOF8PW+0UxpEkZGY0d3U9w9aUvP8fZXRO9QzVfcoBQs8+azLP7LUg0wu/PyLeX5tvs1mq59S3YaEwKBgFLmKx8lWQxIXFEe7HyyNd9Eh2p8cIDaPW5zPZutwgxut54O3CDJHNS6cOm3fHhplPdywN9BiFh/5+yUVYjMpd0EB0dTI0IVkQHQ62KRQsECKJTZsKzjN02VJ87iWlXLjDHXlT6eEVjC6xpH2lgVsQUuYWoYyy8hZXfybTNl8Im9AoGBAKIno3nImrOGwsNnUO7Vtu1bwJla3EmWv29DAPCFANpJuLcOPEJ1dwrtaJuOjmpVW+TRFD7c3ipJE+zyot60pcQd4WbguT4PgI0zq2eljTYzBq7IdmiLB6RadGA2oeNExy721iHaHcwsunwriGaCS7dntfltJ97H4LBvcNiat7b9AoGBALFY/ztZ/JtQLcDJU63r3GT62UdV9h8P94/tlyn/y9YsVwb0cK87DwSuGCDh1li6jcF+NWOEHbme6iUwXKo/lOFYHHwC8olA2jze2pTduD494C6y1vlBl3d5Ud35D6NEastVtieFKkh5mz1llylWZUbwsqPow46IDBP3JY/poyF2";
                GATEWAY_PUBLIC_KEY = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCwFgHD4kzEVPdOj03ctKM7KV+16bWZ5BMNgvEeuEQwfQYkRVwI9HFOGkwNTMn5hiJXHnlXYCX+zp5r6R52MY0O7BsTCLT7aHaxsANsvI9ABGx3OaTVlPB59M6GPbJh0uXvio0m1r/lTW3Z60RU6Q3oid/rNhP3CiNgg0W6O3AGqwIDAQAB";
                APP_ID = "10000000000000190010";
//                MER_ID = "240204150953";
                API_HOST = "https://apipcs4.dccnet.com.cn";
//                MER_PRTCL_NO = "2402041509530201";
//                MER_ACCT = "1102180309000106331";
//                ELIFE_MER_ID="24020078446";
                MER_ID = "240299210037";
                MER_PRTCL_NO = "2402992100370201";
                MER_ACCT = "2402000309068187427";
                ELIFE_MER_ID = "24020078446";
                break;
            case "PRO":
                QRCODE_PRIVATE_KEY = "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQC5nzYVQtTxH1hgDETVwVafArBbghdwxBO7O6wUJ9UAv1uAo7giDIFpHZfVKynf+zOqNj1h/OC6drqN/GH5mmBtks8X/kyyAbpG8xWE8LtNRXs+AloYugvtAprAmDiDZ2BrwYyrPQU76127i0C6jHuTVuAykfjByT7dW4d59x1geFPYVM+F/P1XS60mC5nFTdO8GnGUUx280jUGT/Wug4arHpI8+qU+D0BeTywXfWiLHdeyHNfU5pmnkhexLlP2o10EIZIkA9FDDUJnRH4Zt1MA+cHHDj/MkiJUIniEIR3OK4qfqtnTANYGig+f4zPcFMHQ7958igfuIeCCLm/ZNwiTAgMBAAECggEAQSVwnMuk4q9mm+cSbZb6aLpP3P3ubiRS7H6H6VcFecqvOZm8MS8EaDj7pdQNUU/flRiOOIrA8JBk7xop5KlauHoy9q/IiRz0HJyJ6+t1QSxmkZ/PsSfysY8dcwS5qNyqSYdXcG3tHVeAwSahZBeT82UlMHpsvM59osDR7mtdQxK9iqntN+AGzAJ0jL7CVuY0WwlkBwCPLUOZ8r9LE/wZq+4jSoPgyOvZaWta6vmVg2GRl+1n/7OVxRbinbNbPSHKs2satp1+XoqV+S8KE10Aw2AcX6zhSwoO7CBIcw/OoB/Xhx005HV/Elm+66WuKlMi09+mT+yXcYzlhqEBeJ+iiQKBgQD66w5L90H5JQkKqqa4+HyLjObOa0ZOlnlgH7kHH4y40btJaXu9bOkiMqeQrrZmOSKDsMrJcXgCKrSwqQo42zzg1/ABH+UOXZ+NS/HxcKb/cWleqIG13gOYrG1WwqbiZCRxo2IpxpZmnzdQyEGJAoe5rEF+HJJM6zuF3RBvdG2GfQKBgQC9YZySbeqtsaahjlVzeW/eq3WU4ytv0t/1QGquXnJW2O8B5hpmE89sRwxReCdEPkq9mcGfp8NuHDdYzRuriPO8s6W0vxFRBnlPbRJh5Qf0jSObGB/J1G5OSTCRV0AXu3i0cvoIQdAczH8bP/qv0yixkDPKA5Q8XK5s297h6bMoTwKBgDSTM/eu41/05qQZhb2UM2R6LZJq39xvoxcFDpvzfGTtbTTAqXDTdTX5LysdsJJSvmyhipwS7nZlxF6PzNiE94iVNnDF4hTUgS32D8frNtKnTNDMtgEJd+9xkadwOc+N9CTrexINzk3KZqjCjRjMMuwwr7hg/Dapw1sVKvBvkNNxAoGAIYybSi2Ct4aTOGeYp75JnS7Ow7OCzGqVFkN1IrLEmrIPlUyIPLEhu9LSUdRxUFugrfoBHSGBM454F5kuX7MBStqgbmay0KHO980gxormX+Jo/l7FsuGZMPEyU20bg5jIh18fADt4fMGVeuRYqrFDskETi6QarJ7Wn55L28Wk4W0CgYB7EZKWR9RE/8kQSbwbyED7ljfvIx/6d8mSJQ1ub9HflcXt86vk2wjAuZzKl2ZZuh4x9WjNw6QG4zXSdpD5xc/G1mdrXNTZ6aHfkbmr/GKX1jEB76JNjqNDMZXVkZkgAbHCaBGJzE9KeHb0lM6uziifWOBrOaVVZxAr5Ka3s0RTCg==";
                QRCODE_PUBLIC_KEY = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuZ82FULU8R9YYAxE1cFWnwKwW4IXcMQTuzusFCfVAL9bgKO4IgyBaR2X1Ssp3/szqjY9Yfzguna6jfxh+ZpgbZLPF/5MsgG6RvMVhPC7TUV7PgJaGLoL7QKawJg4g2dga8GMqz0FO+tdu4tAuox7k1bgMpH4wck+3VuHefcdYHhT2FTPhfz9V0utJguZxU3TvBpxlFMdvNI1Bk/1roOGqx6SPPqlPg9AXk8sF31oix3XshzX1OaZp5IXsS5T9qNdBCGSJAPRQw1CZ0R+GbdTAPnBxw4/zJIiVCJ4hCEdziuKn6rZ0wDWBooPn+Mz3BTB0O/efIoH7iHggi5v2TcIkwIDAQAB";
                GATEWAY_PUBLIC_KEY = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCMpjaWjngB4E3ATh+G1DVAmQnIpiPEFAEDqRfNGAVvvH35yDetqewKi0l7OEceTMN1C6NPym3zStvSoQayjYV+eIcZERkx31KhtFu9clZKgRTyPjdKMIth/wBtPKjL/5+PYalLdomM4ONthrPgnkN4x4R0+D4+EBpXo8gNiAFsNwIDAQAB";
                APP_ID = "10000000000003160185";
                MER_ID = "240207011184";
                MER_PRTCL_NO = "2402070111840201";
                MER_ACCT = "2402003429000043055";
                ELIFE_MER_ID = "24020092169";
                API_HOST = "https://gw.open.icbc.com.cn";
                break;
        }
    }

    /**
     * 生成签名
     * 使用私钥RSA2方式生成
     *
     * @return
     */
    public static String sign(String dataStr) throws Exception {
        byte[] data = dataStr.getBytes(Charset.forName("UTF-8"));
        String result = RSA.sign(data, Base64.getDecoder().decode(QRCODE_PRIVATE_KEY), RSA.SIGN_SHA256_ALGORITHMS);
        return result;
    }

    /**
     * 使用网关公钥RSA方式进行验证
     *
     * @param data
     * @param sign
     * @return
     * @throws Exception
     */
    public static boolean verify(String data, String sign) throws Exception {
        byte[] dataBytes = data.getBytes(Charset.forName("UTF-8"));
        boolean verify = RSA.verify(dataBytes, Base64.getDecoder().decode(GATEWAY_PUBLIC_KEY), sign, RSA.SIGN_SHA1_ALGORITHMS);
        return verify;
    }

    /**
     * 生成待签名字符串
     *
     * @param path
     * @param params
     * @return
     */
    public static String buildOrderedSignStr(String path, Map<String, String> params) {
        Map<String, String> sortedMap = new TreeMap();
        sortedMap.putAll(params);
        List<String> listParam = new ArrayList<String>();
        for (Map.Entry<String, String> entry : sortedMap.entrySet()) {
            if (IcbcStringUtils.areNotEmpty(entry.getKey(), entry.getValue())) {
                listParam.add(entry.getKey() + "=" + entry.getValue());
            }
        }
        String result = path + "?" + String.join("&", listParam);
        return result;
    }

    public static IcbcHashMap buildUrlQueryParams(IcbcHashMap params) {
        IcbcHashMap urlQueryParams = new IcbcHashMap();
        Iterator var3 = params.entrySet().iterator();

        while (var3.hasNext()) {
            Map.Entry<String, String> entry = (Map.Entry) var3.next();
            String key = (String) entry.getKey();
            if (HttpRequestParamsUtils.isApiParam(key)) {
                urlQueryParams.put(key, (String) entry.getValue());
            }
        }

        return urlQueryParams;
    }

    public static IcbcHashMap buildBodyParams(IcbcHashMap params) {
        IcbcHashMap urlQueryParams = new IcbcHashMap();
        Iterator var3 = params.entrySet().iterator();

        while (var3.hasNext()) {
            Map.Entry<String, String> entry = (Map.Entry) var3.next();
            String key = (String) entry.getKey();
            if (!HttpRequestParamsUtils.isApiParam(key)) {
                urlQueryParams.put(key, (String) entry.getValue());
            }
        }

        return urlQueryParams;
    }

    public static String buildGetUrl(String strUrl, Map<String, String> params, String charset) throws Exception {
        if (params != null && params.size() != 0) {
            StringBuilder sb = new StringBuilder(strUrl);

            try {
                if (IcbcStringUtils.isEmpty((new URL(strUrl)).getQuery()) && !strUrl.endsWith("?")) {
                    sb.append('?');
                }
            } catch (MalformedURLException var13) {
                System.out.println("url exception. url: " + strUrl + "," + var13);
                throw new Exception("url exception. url: " + strUrl);
            }

            Set<Map.Entry<String, String>> entries = params.entrySet();
            boolean hasParam = false;
            boolean shouldAddAnd = strUrl.contains("?") ? !strUrl.endsWith("&") : false;
            Iterator var7 = entries.iterator();

            while (var7.hasNext()) {
                Map.Entry<String, String> entry = (Map.Entry) var7.next();
                String name = (String) entry.getKey();
                String value = (String) entry.getValue();
                if (IcbcStringUtils.areNotEmpty(new String[]{name, value})) {
                    if (hasParam) {
                        sb.append("&");
                    } else {
                        if (shouldAddAnd) {
                            sb.append("&");
                        }
                        hasParam = true;
                    }
                    try {
                        sb.append(name).append("=").append(URLEncoder.encode(value, charset));
                    } catch (UnsupportedEncodingException var12) {
                        System.out.println("param urlencode exception. value: " + value);
                        throw new Exception("param urlencode exception. value: " + value, var12);
                    }
                }
            }

            return sb.toString();
        } else {
            return strUrl;
        }
    }

    public static String buildForm(String baseUrl, Map<String, String> parameters) {
        StringBuffer sb = new StringBuffer();
        sb.append("<form name=\"auto_submit_form\" method=\"post\" action=\"");
        sb.append(baseUrl);
        sb.append("\">\n");
        sb.append(buildHiddenFields(parameters));
        sb.append("<input type=\"submit\" value=\"立刻提交\" style=\"display:none\" >\n");
        sb.append("</form>\n");
        sb.append("<script>document.forms[0].submit();</script>");
        String form = sb.toString();
        return form;
    }

    private static String buildHiddenFields(Map<String, String> parameters) {
        if (parameters != null && !parameters.isEmpty()) {
            StringBuffer sb = new StringBuffer();
            Set<String> keys = parameters.keySet();
            Iterator var3 = keys.iterator();

            while (var3.hasNext()) {
                String key = (String) var3.next();
                String value = (String) parameters.get(key);
                if (key != null && value != null) {
                    sb.append(buildHiddenField(key, value));
                }
            }

            String result = sb.toString();
            return result;
        } else {
            return "";
        }
    }

    private static String buildHiddenField(String key, String value) {
        StringBuffer sb = new StringBuffer();
        sb.append("<input type=\"hidden\" name=\"");
        sb.append(key);
        sb.append("\" value=\"");
        String a = value.replace("\"", "&quot;");
        sb.append(a).append("\">\n");
        return sb.toString();
    }

    public static void main(String[] args) throws Exception {
        String sign = sign("1");
        boolean verify = verify("1", sign);
        System.out.println(sign);
        System.out.println(verify);

    }


}
